﻿using System;
using System.Text;
using BoxSauce.AgencyToolkit.Strings;

namespace BoxSauce.AgencyToolkit.Extensions
{
    public static class StringExtensions
    {
        /// <summary>
        /// Retrieves a substring from this instance. The substring
        /// contains the amount of words specified in wordCount
        /// </summary>
        /// <param name="stringToChange"><see cref="System.String" /> to return substring from</param>
        /// <param name="wordCount">Number of words to return</param>
        /// <param name="elipsis">If true adds elipsis character to end of string</param>
        /// <returns>Substring of instance containing wordCount amount of words.</returns>
        public static string SubstringWords(this string stringToChange, int wordCount, bool elipsis = false)
        {
            return StringHelpers.SubstringWords(stringToChange, wordCount, elipsis);
        }

        /// <summary>
        /// Returns the given string truncated to the specified length, suffixed with the given value
        /// </summary>
        /// <param name="input"><see cref="System.String" /> to truncate</param>
        /// <param name="length">Maximum length of return string</param>
        /// <param name="suffix">The value to suffix the return value with (if truncation is performed)</param>
        /// <returns></returns>
        public static string Truncate(this string input, int length, string suffix)
        {
            return StringHelpers.Truncate(input, length, suffix);
        }

        /// <summary>
        /// Check to see if string is not null or empty
        /// </summary>
        /// <param name="stringToTest">String to check for null</param>
        /// <returns>Boolean, true if string is not null or empty</returns>
        public static bool IsNotNull(this string stringToTest)
        {
            if (!String.IsNullOrEmpty(stringToTest))
                return true;

            return false;
        }

        /// <summary>
        /// Check to see if string is null or empty
        /// </summary>
        /// <param name="stringToTest">String to check for null</param>
        /// <returns>Boolean, true if string is null or empty</returns>
        public static bool IsNull(this string stringToTest)
        {
            if (String.IsNullOrEmpty(stringToTest))
                return true;

            return false;
        }

        /// <summary>
        /// Replaces the format item in a specified string with the string 
        /// representation of a corresponding object in a specified array.
        /// </summary>
        /// <example>string message = "Welcome {0} (Last login: {1})".FormatString(userName, lastLogin);</example>
        /// <param name="format">A composite format string</param>
        /// <param name="args">An object array that contains zero or more objects to format</param>
        /// <returns></returns>
        public static string FormatString(this string format, params object[] args)
        {
            return String.Format(format, args);
        }

        /// <summary>
        /// Convert to String to ByteArray
        /// </summary>
        /// <param name="str"></param>
        /// <returns>UTF8 string of bytearray</returns>
        public static byte[] ToByteArray(this string str)
        {
            return Encoding.ASCII.GetBytes(str);
        }

        /// <summary>
        /// Converts string to ByteArrayUTF8
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] ToByteArrayUtf8(this string str)
        {
            return new UTF8Encoding().GetBytes(str);
        }

        /// <summary>
        /// Converts string to ByteArrayBase64
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] ToByteArrayBase64(this string str)
        {
            return Convert.FromBase64String(str);
        }

        /// <summary>
        /// Makes first letter uppercase
        /// </summary>
        /// <param name="str">String to make first letter uppercase on</param>
        /// <returns></returns>
        public static string UppercaseFirst(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return string.Empty;
            }
            var a = str.ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);
        }

        /// <summary>
        /// Uppercases each first letter of every word
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UppercaseWords(string str)
        {
            char[] array = str.ToCharArray();
            // Handle the first letter in the string.
            if (array.Length >= 1)
            {
                if (char.IsLower(array[0]))
                {
                    array[0] = char.ToUpper(array[0]);
                }
            }
            // Scan through the letters, checking for spaces.
            // ... Uppercase the lowercase letters following spaces.
            for (var i = 1; i < array.Length; i++)
            {
                if (array[i - 1] == ' ' && char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
            return new string(array);
        }

        public static string GetMD5HashCode(this string str)
        {
            return Cryptography.Hashing.Hash(str);
        }
    }
}
